import numpy as np
import tensorflow as tf
from sklearn.preprocessing import MinMaxScaler
import sympy
import math

# 定义预定值
x0 = np.array([37,36,40])  # 初始值
E = 10**(-4)  # 10 ** (-6)  # 到达精度就停止

# 定义函数及导数
f = lambda x: np.array(x[0] - x[1] + 2 * (x[0] ** 2) + 2 * x[0] * x[1] + x[1] ** 2)  # 定义原函数
f_d = lambda x: np.array([1 + 4 * x[0] + 2 * x[1], -1 + 2 * x[0] + 2 * x[1]])  # 导数

# 定义BP神经网络模型
model = tf.keras.Sequential([
    tf.keras.layers.Dense(12, activation='relu', input_shape=(3,)),
    tf.keras.layers.Dense(1, activation='linear')
])

# 编译模型
model.compile(optimizer='adam', loss='mean_squared_error')

# 生成训练数据
x1_values = np.array([15, 20, 25, 30, 35, 40, 45])
x2_values = np.array([25, 30, 35, 40, 45, 50, 55])
x3_values = np.array([35, 40, 45, 50, 55, 60, 65])
x1_mesh, x2_mesh, x3_mesh = np.meshgrid(x1_values, x2_values, x3_values)
f_values = -(x1_mesh - 30) ** 2 - (x2_mesh - 40) ** 2 - (x3_mesh - 50) ** 2 + 2500

# 归一化数据
scaler = MinMaxScaler()
f_values_scaled = scaler.fit_transform(f_values.reshape(-1, 1)).flatten()

# 训练模型
model.fit(np.column_stack((x1_mesh.ravel(), x2_mesh.ravel(), x3_mesh.ravel())), f_values_scaled, epochs=1000, batch_size=32, verbose=0)

# 使用模型进行预测
x_test = np.column_stack((x1_mesh.ravel(), x2_mesh.ravel(), x3_mesh.ravel()))
f_values_pred = model.predict(x_test)

# 反归一化预测值
f_values_pred = scaler.inverse_transform(f_values_pred.reshape(-1, 1)).flatten()

# 找到最大值及其对应的索引
max_index = np.argmax(f_values_pred)

# 计算最大值对应的x1, x2, x3取值
max_x1 = x1_mesh.ravel()[max_index]
max_x2 = x2_mesh.ravel()[max_index]
max_x3 = x3_mesh.ravel()[max_index]

# 打印最大值和对应的x1, x2, x3取值
max_f_value = f_values_pred[max_index]
print("Max F(X) value:", max_f_value)
print("x1, x2, x3 at max F(X):", max_x1, max_x2, max_x3)
